package com.joelbitar.switchctrl;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.net.SocketTimeoutException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpConnectionParams;
import org.apache.http.params.HttpParams;
import org.apache.http.util.ByteArrayBuffer;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.content.Context;
import android.net.http.SslCertificate;
import android.util.Log;

public class Webservice {
	// localhost of host (not emulator) : 10.0.2.2
	
	private static final String JSON_SUCCESS = "success";
	private static final String JSON_DEVICES = "devices";
	private static final String JSON_DEVICE_ID = "id";
	private static final String JSON_DEVICE_NAME = "name";
	private static final String JSON_DEVICE_TYPE = "type";
	private static final String JSON_DEVICE_STATUS = "status";
	private static final String REQUEST_PARAMETER = "request";
	
	
	
	private static final boolean realrequest = (10 == 10) ? true : false;
	private static final int forcedsleep = 200;
	
	private Context context;
	public void setContext(Context context)
	{
		this.context = context;
	}
	
	
	private String getHttpResponseString(Request requestObject) {
		
		String resultString = "nothing";
		Log.w("requeststring", "Request String");
		String requestString = requestObject.getUrl() + "?" + requestObject.getRequestGetString();
    	Log.i("requeststring", requestString);
		


    	if(this.realrequest){
	    	BufferedReader in = null;
	        try {
	            HttpClient client = new DefaultHttpClient();
	            HttpPost request = new HttpPost(requestObject.getUrl());
	            //HttpPost request = new HttpPost("http://10.0.2.2/bounce.php");
	            /*
	            List<NameValuePair> postParameters = new ArrayList<NameValuePair>();
	            postParameters.add(new BasicNameValuePair("u", "username"));
	            postParameters.add(new BasicNameValuePair("p", "5f4dcc3b5aa765d61d8327deb882cf99"));
	            postParameters.add(new BasicNameValuePair("list", "true"));
	            */
	            
	            Log.i("request", "Sending the requset.. sooon");
	            
	            List<NameValuePair> postParameters = requestObject.getRequestNameValuePairs();
	            
	            for(int i = 0; i < postParameters.size(); i += 1) {
	            	Log.i("postParameter" , postParameters.get(i).getName() + " = " + postParameters.get(i).getValue());
	            }
	            
	            UrlEncodedFormEntity formEntity = new UrlEncodedFormEntity(postParameters);
	
	            request.setEntity(formEntity);
	            HttpResponse response = client.execute(request);
	            in = new BufferedReader(new InputStreamReader(response.getEntity().getContent()));
	
	            StringBuffer sb = new StringBuffer("");
	            String line = "";
	            String NL = System.getProperty("line.separator");
	            while ((line = in.readLine()) != null) {
	                sb.append(line + NL);
	            }
	            in.close();
	
	            resultString = sb.toString();
	            
	        } catch (ClientProtocolException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			} finally {
	            if (in != null) {
	                try {
	                    in.close();
	                } catch (IOException e) {
	                    e.printStackTrace();
	                }
	            }
	        }
    	}
        Log.i("result" , resultString);
		
    	/*
    	if(this.realrequest){
        try {
        	
        	
        	
        	// TODO: Handle exceptions gracefully.
        	HttpGet httpGet = new HttpGet(requestString);
        	HttpParams httpParameters = new BasicHttpParams();
        	// Set the timeout in milliseconds until a connection is established.
        	int timeoutConnection = 3000;
        	HttpConnectionParams.setConnectionTimeout(httpParameters, timeoutConnection);
        	// Set the default socket timeout (SO_TIMEOUT) 
        	// in milliseconds which is the timeout for waiting for data.
        	int timeoutSocket = 5000;
        	HttpConnectionParams.setSoTimeout(httpParameters, timeoutSocket);

        	DefaultHttpClient httpClient = new DefaultHttpClient(httpParameters);
        	HttpResponse response = httpClient.execute(httpGet);

        	InputStream in = response.getEntity().getContent();
        	
        	try{
                BufferedReader reader = new BufferedReader(new InputStreamReader(in));
                StringBuilder str = new StringBuilder();
                String line = null;
                while((line = reader.readLine()) != null){
                    str.append(line + "\n");
                }
                in.close();
                resultString = str.toString();
            }catch(Exception ex){
            	resultString = "Error";
            }
        	
        	
            Log.i("response", resultString);
            
        	
            
        } catch(SocketTimeoutException e) {
        	e.printStackTrace();
        }catch (Exception e) {
            e.printStackTrace();
        }
    	
    	}
    	*/
        if(Webservice.realrequest == false){
        	resultString = "{\"devices\":[{\"id\":\"1\",\"name\":\"Example Device\",\"status\":\"1\"},{\"id\":\"55\",\"name\":\"Example Device2\",\"status\":\"1\"},{\"id\":\"56\",\"name\":\"Example Device3\",\"status\":\"0\"},{\"id\":\"57\",\"name\":\"Example Device 4 with a reaeeeeealy long name\",\"status\":\"0\"},{\"id\":\"58\",\"name\":\"Example Device5\",\"status\":\"1\"},{\"id\":\"59\",\"name\":\"Example Device6\",\"status\":\"0\"},{\"id\":\"60\",\"name\":\"Example Device7\",\"status\":\"0\"},{\"id\":\"61\",\"name\":\"Example Device8\",\"status\":\"0\"},{\"id\":\"62\",\"name\":\"Example Device9\",\"status\":\"0\"},{\"id\":\"10\",\"name\":\"Hallen\",\"status\":\"1\"},{\"id\":\"11\",\"name\":\"K\u00f6ksf\u00f6nstret\",\"status\":\"1\"},{\"id\":\"2\",\"name\":\"Lavalampa\",\"status\":\"1\"},{\"id\":\"3\",\"name\":\"H\u00f6ger f\u00f6nster\",\"status\":\"1\"},{\"id\":\"4\",\"name\":\"V\u00e4nster f\u00f6nster\",\"status\":\"1\"}],\"success\":\"true\"}";
        	try {
				Thread.currentThread();
				Thread.sleep(Webservice.forcedsleep);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}        	
        }
        
		Log.i("response", resultString);
        
        return resultString;
	}
	
	private JSONObject encodeJSON(String stringToConvert) {

    	JSONObject json = new JSONObject();
		try{
			json = new JSONObject(stringToConvert);
		}catch(JSONException e){
			e.printStackTrace();
		}
		
		return json;
	}
	
	private JSONObject getJSONResponse(Request request) {
		String serverResponse = getHttpResponseString(request);
		
		JSONObject json = this.encodeJSON(serverResponse);
		
		return json;
	}
	
	public ArrayList<Request> getAllActiveDevicesRequests() {
		Log.w("webservice", "GetAllAcitveDevicesRequests");
		
		ArrayList<Request> requests = new ArrayList<Request>();
		
		ServerDbAdapter adapter = new ServerDbAdapter(this.context);
		
		Log.i("servers", "Getting all active servers");
		ArrayList<Server> activeServers = adapter.getAllActiveServers();
		
		Log.i("servers", "Active servers: " + activeServers.size());
		
		if(activeServers.size() > 0)
		{
			for(int i = 0; i < activeServers.size(); i += 1)
			{
				Log.i("request", "Creating request objects");
				Server server = activeServers.get(i);
				Log.i("name", server.getName());
				Log.i("url", server.getHosturl());
				
				Request request = new Request();
				request.setServer(server);
				request.setList(true);
				
				requests.add(request);
			}
		}
		
		Log.i("requests", "Returning request objects in ArrayList");
		return requests;
	}
	
	public ArrayList<Device> getAllActiveDevices() {
		
		ArrayList<Request> requests = this.getAllActiveDevicesRequests();
		ArrayList<Device> devices = new ArrayList<Device>();
		
		if(requests.size() > 0)
		{
			for(int i = 0; i < requests.size(); i += 1)
			{
				Request request = requests.get(i);
				Response response = this.getResponse(request);
				
				// Add all devices from this response to the arraylist
				
				ArrayList<Device> requestDevices = response.getDevices();
				
				Log.i("getallactivedevices", "Getting all active devices");
				Log.i("activedevices", "Active devices : " + requestDevices.size());
				
				devices.addAll(requestDevices);
				
			}
		}
		
		return devices;
	}
	

	public Response getResponse(Request request) {
		
		JSONObject json = this.getJSONResponse(request);
		
		Response response = new Response();
		response.setRequest(request);
		
		ArrayList<Device> devices = new ArrayList<Device>();
		
		try{
			response.setSuccess(json.getBoolean(Webservice.JSON_SUCCESS));
			
			try{
				JSONArray jsonDevices = json.getJSONArray(Webservice.JSON_DEVICES);
				
				if(jsonDevices.length() > 0){
					
					for(int i = 0; i < jsonDevices.length(); i++)
					{
						JSONObject jsonDevice = jsonDevices.getJSONObject(i);
						
						Device device = new Device();
						int deviceId = jsonDevice.getInt(JSON_DEVICE_ID);
						String name = jsonDevice.getString(JSON_DEVICE_NAME);
						int status = jsonDevice.getInt(JSON_DEVICE_STATUS);
						
						// Setting device props
						device.setDevice_id(deviceId);
						device.setName(name);
						device.setStatus(status);
						// Setting the Server of this Device to the Server that is tied to the Request
						device.setServer(request.getServer());
						
						// TODO real type, instead of just default
						device.setType(Device.DEFAULT_TYPE);
						
						devices.add(device);
					}
					
				}else{
					Log.i("resposne", "No Devices");
				}
				
				
			}catch(JSONException e){
				e.printStackTrace();
			}
			
			// Setting devices to the response
			
			response.setDevices(devices);
			
		}catch(JSONException e){
			e.printStackTrace();
		}
		
		
		return response;
	}
	
}
